package com.dubbo.test.redisNew;

import com.dubbo.test.lock.JedisConnectionUtils;
import redis.clients.jedis.Jedis;
import redis.clients.jedis.Transaction;

import java.util.List;

/**
 * @ Author xsd
 * @ crate time 2020/7/23 15:21
 * @ 描述 开事务-》提交请求-》任务入队列-》执行命令 exec -》事务执行错误
 *  Redis事务的相关命令有Multi、Exec、Discard、Watch和Unwatch
 */
public class RedisTransaction {
    static Jedis jedis = JedisConnectionUtils.getJedis();

    /**
     * zj：开启事务
     * Transaction transaction = jedis.multi();
     * // 提交事务
     * transaction.exec();
     * // 放弃事务
     * transaction.discard();
     * // 监控键
     * jedis.watch("balance", "debt");
     * // 放弃所有被监控的键
     * jedis.unwatch();
     */
    public static boolean isSuccess(String balance, String debt, Long delAmount) throws InterruptedException {
        // Watch 命令用于监视一个(或多个) key
        // 如果在事务执行之前这个(或这些) key 被其他命令所改动，那么事务将被打断
        jedis.watch(balance);
        Long amount = Long.parseLong(jedis.get(balance));
        if (amount < delAmount) {
            //Redis Unwatch 命令用于取消 WATCH 命令对所有 key 的监视。
            jedis.unwatch();
            System.out.println("amount can't Less than delAmount !!!!");
            return false;
        } else {
            //Redis 通过 MULTI 开始一个事务， 然后将多个命令入队到事务中， 最后由 EXEC 命令触发事务
            Transaction transaction = jedis.multi();
            transaction.decrBy(balance, delAmount);
            transaction.incrBy(debt, delAmount);
            //在这里模拟网络延迟时，我们通过redis命令窗口手动去修改balance值。　　　　　　　　
            Thread.sleep(3000);
            List<Object> exec = transaction.exec();
            //执行exec操作时发现balance值被修改，因此终止操作。
            if (exec == null || exec.size() <= 0) {
                transaction.discard();//事务回滚__
                System.out.println("balance is upfated by other person,debt is fail!!!");
                return false;
            }
            System.out.println("After updated balance== " + Long.parseLong(jedis.get(balance)));
            System.out.println("After updated debt== " + Long.parseLong(jedis.get(debt)));
            return true;
        }
    }

    public static void main1(String[] args) {
        boolean isSuccess = false;
        try {
            isSuccess = isSuccess("balance", "debt", 100L);
            System.out.println("事务处理 result：" + isSuccess);
        } catch (InterruptedException e) {
            e.printStackTrace();

        }

    }
}
